package com.spzx.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.domain.Product;
import com.spzx.product.domain.ProductDetails;
import com.spzx.product.domain.ProductSku;
import com.spzx.product.domain.SkuStock;
import com.spzx.product.mapper.ProductDetailsMapper;
import com.spzx.product.mapper.ProductMapper;
import com.spzx.product.mapper.ProductSkuMapper;
import com.spzx.product.mapper.SkuStockMapper;
import com.spzx.product.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品 服务实现类
 * </p>
 *
 * @author atguigu
 * @since 2024-12-20
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {
    @Autowired
    private ProductSkuMapper productSkuMapper;

    @Autowired
    private SkuStockMapper skuStockMapper;

    @Autowired
    private ProductDetailsMapper productDetailsMapper;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public List<Product> selectProductList() {
        return baseMapper.selectProductList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertProduct(Product product) {
        //保存商品信息
        product.setCreateBy(SecurityUtils.getUsername());
        baseMapper.insert(product);


        //product:product_sku   1:n
        //存储sku信息
        List<ProductSku> productSkuList = product.getProductSkuList();
        for (int i = 0; i < productSkuList.size(); i++) {
            ProductSku productSku = productSkuList.get(i);
            productSku.setSkuCode(product.getId() + "_" + (i + 1));
            productSku.setSkuName(product.getName() + " " + productSku.getSkuSpec());
            productSku.setProductId(product.getId());
            productSku.setStatus(0);//初始值
            productSku.setCreateBy(SecurityUtils.getUsername());
            productSkuMapper.insert(productSku);

            //product:sku_stock   1:n
            //product_sku:sku_stock 1:1
            //存库存信息
            SkuStock skuStock = new SkuStock();
            skuStock.setSkuId(productSku.getId());
            skuStock.setTotalNum(productSku.getStockNum());//总库存
            skuStock.setAvailableNum(productSku.getStockNum());//可用库存
            skuStock.setLockNum(0);//锁定库存
            skuStock.setSaleNum(0);//已售库存
            skuStock.setStatus((byte) 0);
            skuStock.setCreateBy(SecurityUtils.getUsername());
            skuStockMapper.insert(skuStock);
        }

        //product:product_details   1:1
        //存商品详情信息
        ProductDetails productDetails = new ProductDetails();
        productDetails.setProductId(product.getId());
        String imagesString = String.join(",", product.getDetailsImageUrlList());
        productDetails.setImageUrls(imagesString);
        productDetailsMapper.insert(productDetails);

        return 1;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteProductByIds(List<Long> ids) {
        // 删除商品
        baseMapper.deleteBatchIds(ids);

        //查询skuIds(先查询)
        LambdaQueryWrapper<ProductSku> queryWrapper = new LambdaQueryWrapper<ProductSku>()
                .in(ProductSku::getProductId, ids)
                .select(ProductSku::getId);
        List<ProductSku> productSkuList = productSkuMapper.selectList(queryWrapper);
        List<Long> skuIds = productSkuList.stream().map(ProductSku::getId).collect(Collectors.toList());

        // 删除商品sku（再删除）
        productSkuMapper.delete(
                new LambdaQueryWrapper<ProductSku>()
                        .in(ProductSku::getProductId, ids)
        );

        //删除商品详情
        productDetailsMapper.delete(
                new LambdaQueryWrapper<ProductDetails>()
                        .in(ProductDetails::getProductId, ids)
        );

        //删除商品库存
        return skuStockMapper.delete(
                new LambdaQueryWrapper<SkuStock>()
                        .in(SkuStock::getSkuId, skuIds)
        );
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateStatus(Long id, Integer status) {

        Product product = new Product();
        product.setId(id);
        product.setStatus(status);
        baseMapper.updateById(product);


        LambdaUpdateWrapper<ProductSku> updateWrapperSku = new LambdaUpdateWrapper<>();
        updateWrapperSku
                .eq(ProductSku::getProductId, id)
                .set(ProductSku::getStatus, status);
        productSkuMapper.update(null, updateWrapperSku);

        LambdaQueryWrapper<ProductSku> queryWrapperSku2 = new LambdaQueryWrapper<>();
        queryWrapperSku2.eq(ProductSku::getProductId, id);
        queryWrapperSku2.select(ProductSku::getId);
        List<Object> productSkuIdList = productSkuMapper.selectObjs(queryWrapperSku2);

        LambdaUpdateWrapper<SkuStock> updateWrapperSS = new LambdaUpdateWrapper<>();
        updateWrapperSS
                .in(SkuStock::getSkuId, productSkuIdList)
                .set(SkuStock::getStatus, status);
        skuStockMapper.update(null, updateWrapperSS);

        String key = "product:sku:data";
        if(status == 1){
            //向bitmap插入当前
            productSkuIdList.forEach(productSkuId -> {
                redisTemplate.opsForValue().setBit(key, (Long)productSkuId, true);
            });
        }else{
            productSkuIdList.forEach(productSkuId -> {
                redisTemplate.opsForValue().setBit(key, (Long)productSkuId, false);
            });
        }
        if(status == 1){
            productSkuIdList.forEach(productSkuId -> {
                redisTemplate.opsForValue().setBit(key, (Long)productSkuId,true);
            });
        }else{
            productSkuIdList.forEach(productSkuId -> {
                redisTemplate.opsForValue().setBit(key, (Long)productSkuId,false);
            });
        }
        return 1;
    }
}
